home *** CD-ROM | disk | FTP | other *** search
/ Nebula 1 / Nebula One.iso / Misc / msql-1.0.6 / src / makedepend / main.c < prev    next >
C/C++ Source or Header  |  1995-01-04  |  14KB  |  654 lines

  1. /* $XConsortium: main.c,v 1.83 94/04/17 20:10:36 gildea Exp $ */
  2. /*
  3.  
  4. Copyright (c) 1993, 1994  X Consortium
  5.  
  6. Permission is hereby granted, free of charge, to any person obtaining a copy
  7. of this software and associated documentation files (the "Software"), to deal
  8. in the Software without restriction, including without limitation the rights
  9. to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10. copies of the Software, and to permit persons to whom the Software is
  11. furnished to do so, subject to the following conditions:
  12.  
  13. The above copyright notice and this permission notice shall be included in
  14. all copies or substantial portions of the Software.
  15.  
  16. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
  19. X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
  20. AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  21. CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  22.  
  23. Except as contained in this notice, the name of the X Consortium shall not be
  24. used in advertising or otherwise to promote the sale, use or other dealings
  25. in this Software without prior written authorization from the X Consortium.
  26.  
  27. */
  28.  
  29. #include "def.h"
  30. #ifdef hpux
  31. #define sigvec sigvector
  32. #endif /* hpux */
  33.  
  34. #ifdef X_POSIX_C_SOURCE
  35. #define _POSIX_C_SOURCE X_POSIX_C_SOURCE
  36. #include <signal.h>
  37. #undef _POSIX_C_SOURCE
  38. #else
  39. #if defined(X_NOT_POSIX) || defined(_POSIX_SOURCE)
  40. #include <signal.h>
  41. #else
  42. #define _POSIX_SOURCE
  43. #include <signal.h>
  44. #undef _POSIX_SOURCE
  45. #endif
  46. #endif
  47.  
  48. #if NeedVarargsPrototypes
  49. #include <stdarg.h>
  50. #endif
  51.  
  52. #ifdef DEBUG
  53. int    _debugmask;
  54. #endif
  55.  
  56. char *ProgramName;
  57.  
  58. char    *directives[] = {
  59.     "if",
  60.     "ifdef",
  61.     "ifndef",
  62.     "else",
  63.     "endif",
  64.     "define",
  65.     "undef",
  66.     "include",
  67.     "line",
  68.     "pragma",
  69.     "error",
  70.     "ident",
  71.     "sccs",
  72.     "elif",
  73.     "eject",
  74.     NULL
  75. };
  76.  
  77. #define MAKEDEPEND
  78. #include "imakemdep.h"    /* from config sources */
  79. #undef MAKEDEPEND
  80.  
  81. struct    inclist inclist[ MAXFILES ],
  82.         *inclistp = inclist,
  83.         maininclist;
  84.  
  85. char    *filelist[ MAXFILES ];
  86. char    *includedirs[ MAXDIRS + 1 ];
  87. char    *notdotdot[ MAXDIRS ];
  88. char    *objprefix = "";
  89. char    *objsuffix = OBJSUFFIX;
  90. char    *startat = "# DO NOT DELETE THIS LINE -- make depend depends on it.";
  91.  
  92. int    width = 78;
  93. boolean    append = FALSE;
  94. boolean    printed = FALSE;
  95. boolean    verbose = FALSE;
  96. boolean    show_where_not = FALSE;
  97. boolean warn_multiple = FALSE;    /* Warn on multiple includes of same file */
  98.  
  99. static
  100. #ifdef SIGNALRETURNSINT
  101. int
  102. #else
  103. void
  104. #endif
  105. catch (sig)
  106.     int sig;
  107. {
  108.     fflush (stdout);
  109.     fatalerr ("got signal %d\n", sig);
  110. }
  111.  
  112. #if defined(USG) || (defined(SYSV386) && defined(SYSV)) || defined(WIN32)
  113. #define USGISH
  114. #endif
  115.  
  116.  
  117. main(argc, argv)
  118.     int    argc;
  119.     char    **argv;
  120. {
  121.     register char    **fp = filelist;
  122.     register char    **incp = includedirs;
  123.     register char    *p;
  124.     register struct inclist    *ip;
  125.     char    *makefile = NULL;
  126.     struct filepointer    *filecontent;
  127.     struct symtab *psymp = predefs;
  128.     char *endmarker = NULL;
  129.     char *defincdir = NULL;
  130.  
  131.     ProgramName = argv[0];
  132.  
  133.     while (psymp->s_name)
  134.     {
  135.         define2(psymp->s_name, psymp->s_value, &maininclist);
  136.         psymp++;
  137.     }
  138.     if (argc == 2 && argv[1][0] == '@') {
  139.         struct stat ast;
  140.         int afd;
  141.         char *args;
  142.         char **nargv;
  143.         int nargc;
  144.         char quotechar = '\0';
  145.  
  146.         nargc = 1;
  147.         if ((afd = open(argv[1]+1, O_RDONLY)) < 0)
  148.         fatalerr("cannot open \"%s\"\n", argv[1]+1);
  149.         fstat(afd, &ast);
  150.         args = (char *)malloc(ast.st_size + 1);
  151.         if ((ast.st_size = read(afd, args, ast.st_size)) < 0)
  152.         fatalerr("failed to read %s\n", argv[1]+1);
  153.         args[ast.st_size] = '\0';
  154.         close(afd);
  155.         for (p = args; *p; p++) {
  156.         if (quotechar) {
  157.             if (quotechar == '\\' ||
  158.             (*p == quotechar && p[-1] != '\\'))
  159.             quotechar = '\0';
  160.             continue;
  161.         }
  162.         switch (*p) {
  163.         case '\\':
  164.         case '"':
  165.         case '\'':
  166.             quotechar = *p;
  167.             break;
  168.         case ' ':
  169.         case '\n':
  170.             *p = '\0';
  171.             if (p > args && p[-1])
  172.             nargc++;
  173.             break;
  174.         }
  175.         }
  176.         if (p[-1])
  177.         nargc++;
  178.         nargv = (char **)malloc(nargc * sizeof(char *));
  179.         nargv[0] = argv[0];
  180.         argc = 1;
  181.         for (p = args; argc < nargc; p += strlen(p) + 1)
  182.         if (*p) nargv[argc++] = p;
  183.         argv = nargv;
  184.     }
  185.     for(argc--, argv++; argc; argc--, argv++) {
  186.             /* if looking for endmarker then check before parsing */
  187.         if (endmarker && strcmp (endmarker, *argv) == 0) {
  188.             endmarker = NULL;
  189.             continue;
  190.         }
  191.         if (**argv != '-') {
  192.             /* treat +thing as an option for C++ */
  193.             if (endmarker && **argv == '+')
  194.                 continue;
  195.             *fp++ = argv[0];
  196.             continue;
  197.         }
  198.         switch(argv[0][1]) {
  199.         case '-':
  200.             endmarker = &argv[0][2];
  201.             if (endmarker[0] == '\0') endmarker = "--";
  202.             break;
  203.         case 'D':
  204.             if (argv[0][2] == '\0') {
  205.                 argv++;
  206.                 argc--;
  207.             }
  208.             for (p=argv[0] + 2; *p ; p++)
  209.                 if (*p == '=') {
  210.                     *p = ' ';
  211.                     break;
  212.                 }
  213.             define(argv[0] + 2, &maininclist);
  214.             break;
  215.         case 'I':
  216.             if (incp >= includedirs + MAXDIRS)
  217.                 fatalerr("Too many -I flags.\n");
  218.             *incp++ = argv[0]+2;
  219.             if (**(incp-1) == '\0') {
  220.                 *(incp-1) = *(++argv);
  221.                 argc--;
  222.             }
  223.             break;
  224.         case 'Y':
  225.             defincdir = argv[0]+2;
  226.             break;
  227.         /* do not use if endmarker processing */
  228.         case 'a':
  229.             if (endmarker) break;
  230.             append = TRUE;
  231.             break;
  232.         case 'w':
  233.             if (endmarker) break;
  234.             if (argv[0][2] == '\0') {
  235.                 argv++;
  236.                 argc--;
  237.                 width = atoi(argv[0]);
  238.             } else
  239.                 width = atoi(argv[0]+2);
  240.             break;
  241.         case 'o':
  242.             if (endmarker) break;
  243.             if (argv[0][2] == '\0') {
  244.                 argv++;
  245.                 argc--;
  246.                 objsuffix = argv[0];
  247.             } else
  248.                 objsuffix = argv[0]+2;
  249.             break;
  250.         case 'p':
  251.             if (endmarker) break;
  252.             if (argv[0][2] == '\0') {
  253.                 argv++;
  254.                 argc--;
  255.                 objprefix = argv[0];
  256.             } else
  257.                 objprefix = argv[0]+2;
  258.             break;
  259.         case 'v':
  260.             if (endmarker) break;
  261.             verbose = TRUE;
  262. #ifdef DEBUG
  263.             if (argv[0][2])
  264.                 _debugmask = atoi(argv[0]+2);
  265. #endif
  266.             break;
  267.         case 's':
  268.             if (endmarker) break;
  269.             startat = argv[0]+2;
  270.             if (*startat == '\0') {
  271.                 startat = *(++argv);
  272.                 argc--;
  273.             }
  274.             if (*startat != '#')
  275.                 fatalerr("-s flag's value should start %s\n",
  276.                     "with '#'.");
  277.             break;
  278.         case 'f':
  279.             if (endmarker) break;
  280.             makefile = argv[0]+2;
  281.             if (*makefile == '\0') {
  282.                 makefile = *(++argv);
  283.                 argc--;
  284.             }
  285.             break;
  286.  
  287.         case 'm':
  288.             warn_multiple = TRUE;
  289.             break;
  290.             
  291.         /* Ignore -O, -g so we can just pass ${CFLAGS} to
  292.            makedepend
  293.          */
  294.         case 'O':
  295.         case 'g':
  296.             break;
  297.         default:
  298.             if (endmarker) break;
  299.     /*        fatalerr("unknown opt = %s\n", argv[0]); */
  300.             warning("ignoring option %s\n", argv[0]);
  301.         }
  302.     }
  303.     if (!defincdir) {
  304. #ifdef PREINCDIR
  305.         if (incp >= includedirs + MAXDIRS)
  306.         fatalerr("Too many -I flags.\n");
  307.         *incp++ = PREINCDIR;
  308. #endif
  309.         if (incp >= includedirs + MAXDIRS)
  310.         fatalerr("Too many -I flags.\n");
  311.         *incp++ = INCLUDEDIR;
  312. #ifdef POSTINCDIR
  313.         if (incp >= includedirs + MAXDIRS)
  314.         fatalerr("Too many -I flags.\n");
  315.         *incp++ = POSTINCDIR;
  316. #endif
  317.     } else if (*defincdir) {
  318.         if (incp >= includedirs + MAXDIRS)
  319.         fatalerr("Too many -I flags.\n");
  320.         *incp++ = defincdir;
  321.     }
  322.  
  323.     redirect(startat, makefile);
  324.  
  325.     /*
  326.      * catch signals.
  327.      */
  328.  
  329.     /*
  330.     ** Recoded so as not to use sigaction  -  Bambi
  331.     */
  332.  
  333. #ifdef SIGHUP
  334.     signal (SIGHUP, catch);
  335. #endif
  336. #ifdef SIGINT
  337.     signal (SIGINT, catch);
  338. #endif
  339. #ifdef SIGQUIT
  340.     signal (SIGQUIT, catch);
  341. #endif
  342. #ifdef SIGILL
  343.     signal (SIGILL, catch);
  344. #endif
  345. #ifdef SIGBUS
  346.     signal (SIGBUS, catch);
  347. #endif
  348. #ifdef SIGSEGV
  349.     signal (SIGSEGV, catch);
  350. #endif
  351. #ifdef SIGSYS
  352.     signal (SIGSYS, catch);
  353. #endif
  354.  
  355.     /*
  356.      * now peruse through the list of files.
  357.      */
  358.     for(fp=filelist; *fp; fp++) {
  359.         filecontent = getfile(*fp);
  360.         ip = newinclude(*fp, (char *)NULL);
  361.  
  362.         find_includes(filecontent, ip, ip, 0, FALSE);
  363.         freefile(filecontent);
  364.         recursive_pr_include(ip, ip->i_file, base_name(*fp));
  365.         inc_clean();
  366.     }
  367.     if (printed)
  368.         printf("\n");
  369.     exit(0);
  370. }
  371.  
  372. struct filepointer *getfile(file)
  373.     char    *file;
  374. {
  375.     register int    fd;
  376.     struct filepointer    *content;
  377.     struct stat    st;
  378.  
  379.     content = (struct filepointer *)malloc(sizeof(struct filepointer));
  380.     if ((fd = open(file, O_RDONLY)) < 0) {
  381.         warning("cannot open \"%s\"\n", file);
  382.         content->f_p = content->f_base = content->f_end = (char *)malloc(1);
  383.         *content->f_p = '\0';
  384.         return(content);
  385.     }
  386.     fstat(fd, &st);
  387.     content->f_base = (char *)malloc(st.st_size+1);
  388.     if (content->f_base == NULL)
  389.         fatalerr("cannot allocate mem\n");
  390.     if ((st.st_size = read(fd, content->f_base, st.st_size)) < 0)
  391.         fatalerr("failed to read %s\n", file);
  392.     close(fd);
  393.     content->f_len = st.st_size+1;
  394.     content->f_p = content->f_base;
  395.     content->f_end = content->f_base + st.st_size;
  396.     *content->f_end = '\0';
  397.     content->f_line = 0;
  398.     return(content);
  399. }
  400.  
  401. freefile(fp)
  402.     struct filepointer    *fp;
  403. {
  404.     free(fp->f_base);
  405.     free(fp);
  406. }
  407.  
  408. char *copy(str)
  409.     register char    *str;
  410. {
  411.     register char    *p = (char *)malloc(strlen(str) + 1);
  412.  
  413.     strcpy(p, str);
  414.     return(p);
  415. }
  416.  
  417. match(str, list)
  418.     register char    *str, **list;
  419. {
  420.     register int    i;
  421.  
  422.     for (i=0; *list; i++, list++)
  423.         if (strcmp(str, *list) == 0)
  424.             return(i);
  425.     return(-1);
  426. }
  427.  
  428. /*
  429.  * Get the next line.  We only return lines beginning with '#' since that
  430.  * is all this program is ever interested in.
  431.  */
  432. char *getline(filep)
  433.     register struct filepointer    *filep;
  434. {
  435.     register char    *p,    /* walking pointer */
  436.             *eof,    /* end of file pointer */
  437.             *bol;    /* beginning of line pointer */
  438.     register    lineno;    /* line number */
  439.  
  440.     p = filep->f_p;
  441.     eof = filep->f_end;
  442.     if (p >= eof)
  443.         return((char *)NULL);
  444.     lineno = filep->f_line;
  445.  
  446.     for(bol = p--; ++p < eof; ) {
  447.         if (*p == '/' && *(p+1) == '*') { /* consume comments */
  448.             *p++ = ' ', *p++ = ' ';
  449.             while (*p) {
  450.                 if (*p == '*' && *(p+1) == '/') {
  451.                     *p++ = ' ', *p = ' ';
  452.                     break;
  453.                 }
  454.                 else if (*p == '\n')
  455.                     lineno++;
  456.                 *p++ = ' ';
  457.             }
  458.             continue;
  459.         }
  460. #ifdef WIN32
  461.         else if (*p == '/' && *(p+1) == '/') { /* consume comments */
  462.             *p++ = ' ', *p++ = ' ';
  463.             while (*p && *p != '\n')
  464.                 *p++ = ' ';
  465.             lineno++;
  466.             continue;
  467.         }
  468. #endif
  469.         else if (*p == '\\') {
  470.             if (*(p+1) == '\n') {
  471.                 *p = ' ';
  472.                 *(p+1) = ' ';
  473.                 lineno++;
  474.             }
  475.         }
  476.         else if (*p == '\n') {
  477.             lineno++;
  478.             if (*bol == '#') {
  479.                 register char *cp;
  480.  
  481.                 *p++ = '\0';
  482.                 /* punt lines with just # (yacc generated) */
  483.                 for (cp = bol+1; 
  484.                      *cp && (*cp == ' ' || *cp == '\t'); cp++);
  485.                 if (*cp) goto done;
  486.             }
  487.             bol = p+1;
  488.         }
  489.     }
  490.     if (*bol != '#')
  491.         bol = NULL;
  492. done:
  493.     filep->f_p = p;
  494.     filep->f_line = lineno;
  495.     return(bol);
  496. }
  497.  
  498. /*
  499.  * Strip the file name down to what we want to see in the Makefile.
  500.  * It will have objprefix and objsuffix around it.
  501.  */
  502. char *base_name(file)
  503.     register char    *file;
  504. {
  505.     register char    *p;
  506.  
  507.     file = copy(file);
  508.     for(p=file+strlen(file); p>file && *p != '.'; p--) ;
  509.  
  510.     if (*p == '.')
  511.         *p = '\0';
  512.     return(file);
  513. }
  514.  
  515. #if defined(USG) && !defined(CRAY) && !defined(SVR4)
  516. int rename (from, to)
  517.     char *from, *to;
  518. {
  519.     (void) unlink (to);
  520.     if (link (from, to) == 0) {
  521.     unlink (from);
  522.     return 0;
  523.     } else {
  524.     return -1;
  525.     }
  526. }
  527. #endif /* USGISH */
  528.  
  529. redirect(line, makefile)
  530.     char    *line,
  531.         *makefile;
  532. {
  533.     struct stat    st;
  534.     FILE    *fdin, *fdout;
  535.     char    backup[ BUFSIZ ],
  536.         buf[ BUFSIZ ];
  537.     boolean    found = FALSE;
  538.     int    len;
  539.  
  540.     /*
  541.      * if makefile is "-" then let it pour onto stdout.
  542.      */
  543.     if (makefile && *makefile == '-' && *(makefile+1) == '\0')
  544.         return;
  545.  
  546.     /*
  547.      * use a default makefile is not specified.
  548.      */
  549.     if (!makefile) {
  550.         if (stat("Makefile", &st) == 0)
  551.             makefile = "Makefile";
  552.         else if (stat("makefile", &st) == 0)
  553.             makefile = "makefile";
  554.         else
  555.             fatalerr("[mM]akefile is not present\n");
  556.     }
  557.     else
  558.         stat(makefile, &st);
  559.     if ((fdin = fopen(makefile, "r")) == NULL)
  560.         fatalerr("cannot open \"%s\"\n", makefile);
  561.     sprintf(backup, "%s.bak", makefile);
  562.     unlink(backup);
  563. #ifdef WIN32
  564.     fclose(fdin);
  565. #endif
  566.     if (rename(makefile, backup) < 0)
  567.         fatalerr("cannot rename %s to %s\n", makefile, backup);
  568. #ifdef WIN32
  569.     if ((fdin = fopen(backup, "r")) == NULL)
  570.         fatalerr("cannot open \"%s\"\n", backup);
  571. #endif
  572.     if ((fdout = freopen(makefile, "w", stdout)) == NULL)
  573.         fatalerr("cannot open \"%s\"\n", backup);
  574.     len = strlen(line);
  575.     while (!found && fgets(buf, BUFSIZ, fdin)) {
  576.         if (*buf == '#' && strncmp(line, buf, len) == 0)
  577.             found = TRUE;
  578.         fputs(buf, fdout);
  579.     }
  580.     if (!found) {
  581.         if (verbose)
  582.         warning("Adding new delimiting line \"%s\" and dependencies...\n",
  583.             line);
  584.         puts(line); /* same as fputs(fdout); but with newline */
  585.     } else if (append) {
  586.         while (fgets(buf, BUFSIZ, fdin)) {
  587.         fputs(buf, fdout);
  588.         }
  589.     }
  590.     fflush(fdout);
  591.     chmod(makefile, st.st_mode);
  592. }
  593.  
  594. #if NeedVarargsPrototypes
  595. fatalerr(char *msg, ...)
  596. #else
  597. /*VARARGS*/
  598. fatalerr(msg,x1,x2,x3,x4,x5,x6,x7,x8,x9)
  599.     char *msg;
  600. #endif
  601. {
  602. #if NeedVarargsPrototypes
  603.     va_list args;
  604. #endif
  605.     fprintf(stderr, "%s: error:  ", ProgramName);
  606. #if NeedVarargsPrototypes
  607.     va_start(args, msg);
  608.     vfprintf(stderr, msg, args);
  609.     va_end(args);
  610. #else
  611.     fprintf(stderr, msg,x1,x2,x3,x4,x5,x6,x7,x8,x9);
  612. #endif
  613.     exit (1);
  614. }
  615.  
  616. #if NeedVarargsPrototypes
  617. warning(char *msg, ...)
  618. #else
  619. /*VARARGS0*/
  620. warning(msg,x1,x2,x3,x4,x5,x6,x7,x8,x9)
  621.     char *msg;
  622. #endif
  623. {
  624. #if NeedVarargsPrototypes
  625.     va_list args;
  626. #endif
  627.     fprintf(stderr, "%s: warning:  ", ProgramName);
  628. #if NeedVarargsPrototypes
  629.     va_start(args, msg);
  630.     vfprintf(stderr, msg, args);
  631.     va_end(args);
  632. #else
  633.     fprintf(stderr, msg,x1,x2,x3,x4,x5,x6,x7,x8,x9);
  634. #endif
  635. }
  636.  
  637. #if NeedVarargsPrototypes
  638. warning1(char *msg, ...)
  639. #else
  640. /*VARARGS0*/
  641. warning1(msg,x1,x2,x3,x4,x5,x6,x7,x8,x9)
  642.     char *msg;
  643. #endif
  644. {
  645. #if NeedVarargsPrototypes
  646.     va_list args;
  647.     va_start(args, msg);
  648.     vfprintf(stderr, msg, args);
  649.     va_end(args);
  650. #else
  651.     fprintf(stderr, msg,x1,x2,x3,x4,x5,x6,x7,x8,x9);
  652. #endif
  653. }
  654.